<?php
/**
 * Класс предок для всех обработчиков-лент.
 * Содержит общую логику для определения параметров модели, создания URL для листалки и маппинга переменных листалки
 *
 * @package default
 * @author Alexander Sibiryakov
 **/
abstract class Action_Community_FeedHandler extends RL_Handler
{
	private $model_params; // параметры модели

	public $aa;

	public $model;

	public function setParam($key, $value) {
		$this->model_params[$key] = $value;
		if (isset($this->model)) $this->model->setModelParams($key, $value);
	}

	public function getParam($key) {
		return $this->model_params[$key];
	}


	private function setAclAssistant(Model_AclAssistant $aa) {
		$this->aa = $aa;
	}

	/**
	 * Определить параметры модели. Из разных источников - GET запрос, данные собранные Acl_Assistant
	 * У всех лент есть общие параметры и есть частные. Общие определяются в этой функции, частные в специальной функции ниже
	 *
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	public function determineModelParams() {
		$tag = NULL;
		// --- tags --- {{{
		if (isset($this->rh->GET['tag'])) {
			$tag_name = mb_strtolower($this->rh->GET['tag']);
			if ( isset($this->aa->acl_data['comity_oid']) && !empty($this->aa->acl_data['comity_oid']) ) {
				$tag = $this->ctx->store->find( 'select objects where tag.name=:0 AND tag.community_oid=:1', array($tag_name, $this->aa->acl_data['comity_oid']))->next();
			} else {
				$tag = $this->ctx->store->find( 'select objects where tag.name=:0', array($tag_name))->next();
			}
			$this->setParam('tag', $tag);
		}
		// --- tags --- }}}

		// --- filter by tdi --- {{{
		if ($this->aa->acl_data['tdi_oid']) { // если внутри раздела фильтруем по его oid
			$tdis = array($this->aa->acl_data['tdi_oid']);
		} else {
			$tdis = $this->getTdiFilterParams();
		}
		$this->setParam('tdis', $tdis);
		// --- filter by tdi --- }}}

		// --- filter by doctype --- {{{
		$this->setParam('filter_by_doctype', $this->getDoctypeFilterParams());
		// --- filter by doctype --- }}}

		// --- filter by day --- {{{
		if ($this->rh->GET['filter_by_day']) $this->setParam('filter_by_day', $this->rh->GET['filter_by_day']);
		// --- filter by day --- }}}

		$this->setParam('page_number' , isset($this->rh->GET['p']) ? $this->rh->GET['p'] : 1 );

		switch ($this->rh->GET['sort']) {
		case 'name':
			$order_by = 'name';
			break;
		case 'title':
			$order_by = 'title';
			break;
		case 'size':
			$order_by = 'size';
			break;
		case 'date':
			$order_by = 'date';
			break;
		case 'status':
			$order_by = 'status';
			break;
		case 'comment_count':
			$order_by = 'comment_count';
			break;
		default :
			$order_by = 'date';
		}
		$this->setParam('order_by', $order_by);

		$this->setParam('community_oid', $this->aa->acl_data['comity_oid']);

		if (isset($this->params['tdi_url'])) {
			$this->setParam('current_tdi_oid', $this->aa->acl_data['tdi_oid']);
		}

		// вызов пользовательской функции определения параметров
		$this->determineCustomModelParams();
	}

	/**
	 * Позволяет пользователю определить дополнительную функцию определения параметров модели
	 *
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	protected function determineCustomModelParams() {

	}

	/**
	 * Это метод возвращающий экземпляр класса реализующего интерфейс FeedInterface.
	 * Определять в обработчиках.
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	abstract protected function getFeedModel();

	protected function init() {
		$this->rh->UseClass('RL_CyrDate');

		$this->aa = $this->module->aa;
		$data = $this->aa->getInfo();
		// HACK : 2008-01-18 : lucky {{{
		// если в разделе, смотрим операции выставленные разделом, иначе -- сообществом.
		$object_oid = isset($data['tdi_oid']) ? $data['tdi_oid'] : $data['comity_oid'];
		$this->aa->getAvailableOperations( $object_oid );

		// }}}

		$this->ctx->mm->setAclAssistant( $this->aa );

		$this->determineModelParams();

		// создадим модель
		$this->model = $this->getFeedModel();
		$this->model->rh = $this->rh;

		// установим параметры модели
		foreach($this->model_params as $name=>$value) {
			$this->model->setModelParams($name, $value);
		}
	}

	/**
	 * Добавляет два нода с информацией для подгрузки в cpaint ответ
	 *
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	final public function addPagerNodes( &$cp ) {

		$ispagecount_node = &$cp->add_node("ispagecount"); // есть ли следующая страница?
		$itemsremaining_node = &$cp->add_node("itemsremaining");

		$pager = $this->getPagerInfo();

		$ispagecount_node->set_data( $pager['ispagecount'] );
		$itemsremaining_node->set_data($pager['items_remaining']);
	}

	/**
	 * Вернет информацию для постраничной листалки, пригодную для отправки в домен шаблонных переменных
	 *
	 * @return array
	 * @author Alexander Sibiryakov
	 **/
	final public function getPagerInfo() {
		$pager = $this->model->getPager();

		if ($this->getParam("page_number") < $pager['pages_count']) {
			$ispagecount = 1; // есть
		} else $ispagecount = 0;

		$items_out = $this->getParam("page_number") * $pager['items_per_page']; // кол-во итемов отправленных юзеру
		$items_remain = $pager['overall_items_count'] - $items_out;

		if ( $items_remain >= $pager['items_per_page'] ) {
			$itemsremaining = $pager['items_per_page'];
		} else $itemsremaining = $items_remain;

		return $pager + array(
			"items_remaining"=>$itemsremaining,
			"ispagecount"=>$ispagecount
			);
	}

	// имя GET параметра для фильра разделов
	public $rq_tdi = 'tdi';
	public $rq_doctype = 'dt';
	public $rq_tag = 'tag';

	public function hrefFilterByDoctype ($doctype)
	{
		$rule = isset($this->params['tdi_url']) ? 'showfeed_tdi' : 'showfeed';

		$ug = new RL_URLGenerator($this->rh->router->getRule($rule));
		$ug->setRouter($this->rh->router);
		$ug->setParams($this->params);
		$GET = $this->rh->GET;
		unset($GET[$this->rq_doctype]);
		if ($doctype === 'all') {
			$ug->setGet($GET);
		} else {
			$ug->setGet(array_merge($GET, array($this->rq_doctype=>$doctype)));
		}
		return $ug->generateUrl();
	} // end of method hrefFilterByDoctype
	public function hrefFilterByTdi ($tdi)
	{
		$rule = isset($this->params['user_url']) ? 'showmember' : 'showfeed';

		$ug = new RL_URLGenerator($this->rh->router->getRule($rule));
		$ug->setRouter($this->rh->router);
		$ug->setParams($this->params);
		$GET = $this->rh->GET;
		unset($GET[$this->rq_tdi]);
		if ($tdi >= 0) {
			$ug->setGet(array_merge($GET, array($this->rq_tdi=>$tdi)));
		} else {
			$ug->setGet($GET);
		}
		return $ug->generateUrl();
	} // end of method hrefFilterByDoctype
	public function hrefFilterByTag ($tag)
	{
		$rule = isset($this->params['tdi_url']) ? 'showfeed_tdi' : 'showfeed';

		$ug = new RL_URLGenerator($this->rh->router->getRule($rule));
		$ug->setRouter($this->rh->router);
		$ug->setParams($this->params);
		$GET = $this->rh->GET;
		unset($GET[$this->rq_tag]);
		if ($tag === 'all') {
			$ug->setGet($GET);
		} else {
			$ug->setGet(array_merge($GET, array($this->rq_tag=>$tag)));
		}
		return $ug->generateUrl();
	} // end of method hrefFilterByDoctype


	public function getDoctypeFilterParams ()
	{
		$res = NULL;
		$GET = $this->ctx->rh->GET;
		if (isset($GET[$this->rq_doctype])) {
			$params = $GET[$this->rq_doctype];
			if (!is_array($params)) $params = array($params);
			$res = $params;
		}
		return $res;
	} // end of method getDoctypeFilterParams
	public function getTagFilterParams ()
	{
		$res = NULL;
		$GET = $this->ctx->rh->GET;
		if (isset($GET[$this->rq_tag])) {
			$params = $GET[$this->rq_tag];
			if (!is_array($params)) $params = array($params);
			$res = $params;
		}
		return $res;
	} // end of method getDoctypeFilterParams
	public function getTdiFilterParams ()
	{
		$GET = $this->ctx->rh->GET;
		if (isset($GET[$this->rq_tdi])) {
			$params = $GET[$this->rq_tdi];
			$res = is_array($params) ? $params : array($params);
		} else {
			$res = array();
		}
		if (array_key_exists(-1, $res)) $res = array(); // Все
		return $res;
	} // end of method getTdiFilterParams

	// общая функциональность рендера для разных типов лент
	public function renderFilters ($view)
	{
		// если нас просят вывести ленту раздела выведем дополнительные данные
		if ( isset($this->params['tdi_url']) ) {
			$this->renderCurrentTdi($view);
		} else {
			// мы не внутри раздела. значит в ленте могут содержаться записи разных
			// разделов. и ее можно фильтровать по этому признаку.
			$this->renderSelectedTdis($view);
		}
		$this->renderSelectedDoctypes($view);
		$this->renderCurrentTag($view);
	} // end of method renderFilters
	public function renderCurrentTdi ($view)
	{
		// если мы внутри раздела, то запишем его текущим.
		$view->data['current_tdi'] = $this->m_tdi->getTdi($this->aa->acl_data['tdi_oid'])->data;
	} // end of method renderCurrentTdi
	public function renderSelectedTdis ($view)
	{
		// создадим список выделенных разделов
		if ($tdis_params = $this->getTdiFilterParams()) {
			$selected_tdis = array();
			foreach ($this->sections as &$tdi_data) {
				$tdi_oid = $tdi_data['oid'];
				if (in_array($tdi_oid, $tdis_params)) {
					$selected_tdis[$tdi_oid] = $tdi_data;
				}
			}
			$view->data['selected_tdis'] = $selected_tdis;
		}
	} // end of method renderSelectedTdis
	public function renderSelectedDoctypes ($view)
	{
		// создадим список выделенных типов документов
		if ($dt_params = $this->getDoctypeFilterParams()) {
			$selected_dt = array();
			foreach ($this->ctx->dt as &$tdi_data) {
				$tdi_oid = $tdi_data['oid'];
				if (in_array($tdi_oid, $dt_params)) {
					$selected_dt[$tdi_oid] = $tdi_data;
				}
			}
			$view->data['selected_dt'] = $selected_dt;
		}
	} // end of method renderSelectedDoctypes
	public function renderCurrentTag ($view)
	{
		// доп переменные если запрос по тегу
		$tag = $this->getParam('tag'); // instanceof fobject

		if ($tag) {
			$view->data['current_tag'] = $tag->data;
			$view->data['tag'] = $tag;
		}
	} // end of method renderCurrentTag

} // END class
